package com.li.netty.time;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.util.Date;

//最简单的方案是构造一个内部的可积累的缓冲，直到4个字节全部接收到了内部缓冲。
public class TimeClientHandler1 extends ChannelInboundHandlerAdapter {
    private ByteBuf buf;

    //ChannelHandler 有2个生命周期的监听方法：handlerAdded()和 handlerRemoved()。你可以完成任意初始化任务只要他不会被阻塞很长的时间。
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        buf = ctx.alloc().buffer(4);
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        buf.release();
        buf = null;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf m = (ByteBuf) msg;
        //首先，所有接收的数据都应该被累积在 buf 变量里。
        buf.writeBytes(m);
        m.release();

        //然后，处理器必须检查 buf 变量是否有足够的数据，在这个例子中是4个字节，然后处理实际的业务逻辑。否则，Netty 会重复调用channelRead() 当有更多数据到达直到4个字节的数据被积累。
        if (buf.readableBytes() >= 4) {
            long currentTimeMillis = (buf.readUnsignedInt() - 2208988800L) * 1000L;
            System.out.println(new Date(currentTimeMillis));
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
/**
 * 尽管第一个解决方案已经解决了 TIME 客户端的问题了，
 * 但是修改后的处理器看起来不那么的简洁，
 * 想象一下如果由多个字段比如可变长度的字段组成的更为复杂的协议时，
 * 你的 ChannelInboundHandler 的实现将很快地变得难以维护。
 */